using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;
using WIT.DAQ.Core.Enums;
using WIT.DAQ.Core.Forms.UserControls;
using WIT.DAQ.Core.Models;

namespace WIT.DAQ.Core.Forms;

/// <summary>
///
/// </summary>
internal class DAQItemEditForm : BaseForm
{
	/// <summary>
	///
	/// </summary>
	/// <param name="daqItem"></param>
	internal delegate void SaveDAQItemHandler(DAQItem daqItem);

	/// <summary>
	/// 当前操作的站点
	/// </summary>
	private readonly Station STATION;

	/// <summary>
	/// 实例化的目的
	/// </summary>
	internal readonly EnumFormPurpose PURPOSE;

	/// <summary>
	/// 当次编辑的采集项
	/// </summary>
	internal readonly DAQItem DAQITEM;

	private const string TITLE_ADD = "添加采集项";

	private const string TITLE_EDIT = "编辑采集项";

	/// <summary>
	/// Required designer variable.
	/// </summary>
	private IContainer components = null;

	private Button btnCancel;

	private Button btnConfirm;

	private Label label1;

	private ComboBox cmbDevices;

	private TextBox txtName;

	private Label label4;

	private Label label5;

	private TextBox txtDesc;

	private Label label6;

	private Label label7;

	private GroupBox grpParams;

	private Panel pnlContainer;

	private ComboBox cmbDataTypes;

	private Label label2;

	private Label label3;

	private Label label8;

	private Label label9;

	private TextBox txtIdentifier;

	/// <summary>
	///
	/// </summary>
	internal event SaveDAQItemHandler SaveDAQItem;

	/// <summary>
	///
	/// </summary>
	/// <param name="station">站点</param>
	/// <param name="purpose">目的</param>
	/// <param name="daqItem">编辑时传入采集项</param>
	/// <param name="appointedDeviceId">指定设备</param>
	internal DAQItemEditForm(Station station, EnumFormPurpose purpose, DAQItem daqItem = null, Guid? appointedDeviceId = null)
	{
		InitializeComponent();
		STATION = station;
		PURPOSE = purpose;
		DAQITEM = daqItem;
		InitDevices();
		InitDataTypes();
		switch (PURPOSE)
		{
		case EnumFormPurpose.Add:
			Text = "添加采集项";
			cmbDevices.SelectedValue = appointedDeviceId ?? new Guid?(STATION.DefaultDeviceId);
			break;
		case EnumFormPurpose.Edit:
			Text = "编辑采集项";
			txtName.Text = DAQITEM.Name;
			txtIdentifier.Text = DAQITEM.Identifier;
			cmbDevices.SelectedValue = appointedDeviceId ?? new Guid?(DAQITEM.DeviceId);
			cmbDataTypes.SelectedValue = DAQITEM.DataType;
			txtDesc.Text = DAQITEM.Desc;
			break;
		}
	}

	private void DAQItemEditForm_Load(object sender, EventArgs e)
	{
		txtName.Select();
	}

	/// <summary>
	/// 加载设备列表
	/// </summary>
	private void InitDevices()
	{
		List<Device> allDevices = Common.GetAllDevices();
		cmbDevices.DataSource = allDevices;
		cmbDevices.DisplayMember = "ShowName";
		cmbDevices.ValueMember = "Id";
	}

	/// <summary>
	/// 加载数据类型
	/// </summary>
	private void InitDataTypes()
	{
		List<object> list = new List<object>();
		foreach (EnumDataType value in Enum.GetValues(typeof(EnumDataType)))
		{
			list.Add(new
			{
				Name = value.ToString(),
				Value = (int)value
			});
		}
		cmbDataTypes.DisplayMember = "Name";
		cmbDataTypes.ValueMember = "Name";
		cmbDataTypes.DataSource = list;
	}

	/// <summary>
	/// 根据通信协议加载采集项参数UserControl
	/// </summary>
	/// <param name="sender"></param>
	/// <param name="e"></param>
	private void cmbDevices_SelectedIndexChanged(object sender, EventArgs e)
	{
		pnlContainer.Controls.Clear();
		Device device = (Device)cmbDevices.SelectedItem;
		if (device == null)
		{
			return;
		}
		switch (device.Protocol)
		{
		case EnumProtocol.OPCUA:
			if (PURPOSE == EnumFormPurpose.Edit)
			{
				pnlContainer.Controls.Add(new UC_DAQItemParams_For_OPCUA(DAQITEM.NodeId));
			}
			else
			{
				pnlContainer.Controls.Add(new UC_DAQItemParams_For_OPCUA());
			}
			break;
		case EnumProtocol.S7:
			if (PURPOSE == EnumFormPurpose.Edit)
			{
				pnlContainer.Controls.Add(new UC_DAQItemParams_For_S7(DAQITEM.Address));
			}
			else
			{
				pnlContainer.Controls.Add(new UC_DAQItemParams_For_S7());
			}
			break;
		case EnumProtocol.ModbusTcp:
			if (PURPOSE == EnumFormPurpose.Edit)
			{
				pnlContainer.Controls.Add(new UC_DAQItemParams_For_ModbusTcp(DAQITEM.Address, DAQITEM.Length));
			}
			else
			{
				pnlContainer.Controls.Add(new UC_DAQItemParams_For_ModbusTcp());
			}
			break;
		case EnumProtocol.ModbusRtu:
			if (PURPOSE == EnumFormPurpose.Edit)
			{
				pnlContainer.Controls.Add(new UC_DAQItemParams_For_ModbusRtu(DAQITEM.Address, DAQITEM.Length));
			}
			else
			{
				pnlContainer.Controls.Add(new UC_DAQItemParams_For_ModbusRtu());
			}
			break;
		default:
			throw new Exception($"未知的通信协议[{device.Protocol}]");
		case EnumProtocol.Socket:
			break;
		}
		AdjustUCControls();
	}

	/// <summary>
	/// 根据数据类型加载UC中不同的内容
	/// </summary>
	/// <param name="sender"></param>
	/// <param name="e"></param>
	private void cmbDataTypes_SelectedIndexChanged(object sender, EventArgs e)
	{
		AdjustUCControls();
	}

	/// <summary>
	/// 根据协议和数据类型加载UC中不同的内容
	/// </summary>
	private void AdjustUCControls()
	{
		Device device = (Device)cmbDevices.SelectedItem;
		if (device == null || cmbDataTypes.SelectedValue == null)
		{
			return;
		}
		EnumDataType enumDataType = (EnumDataType)Enum.Parse(typeof(EnumDataType), cmbDataTypes.SelectedValue.ToString(), ignoreCase: true);
		switch (device.Protocol)
		{
		case EnumProtocol.OPCUA:
			break;
		case EnumProtocol.S7:
			break;
		case EnumProtocol.ModbusTcp:
		{
			UC_DAQItemParams_For_ModbusTcp uC_DAQItemParams_For_ModbusTcp = (UC_DAQItemParams_For_ModbusTcp)pnlContainer.Controls[0];
			Panel panel2 = (Panel)uC_DAQItemParams_For_ModbusTcp.Controls.Find("pnlStringParams", searchAllChildren: true)[0];
			if (enumDataType == EnumDataType.String)
			{
				panel2.Visible = true;
			}
			else
			{
				panel2.Visible = false;
			}
			break;
		}
		case EnumProtocol.ModbusRtu:
		{
			UC_DAQItemParams_For_ModbusRtu uC_DAQItemParams_For_ModbusRtu = (UC_DAQItemParams_For_ModbusRtu)pnlContainer.Controls[0];
			Panel panel = (Panel)uC_DAQItemParams_For_ModbusRtu.Controls.Find("pnlStringParams", searchAllChildren: true)[0];
			if (enumDataType == EnumDataType.String)
			{
				panel.Visible = true;
			}
			else
			{
				panel.Visible = false;
			}
			break;
		}
		case EnumProtocol.Socket:
			break;
		default:
			throw new Exception($"未知的通信协议[{device.Protocol}]");
		}
	}

	/// <summary>
	/// 确认
	/// </summary>
	/// <param name="sender"></param>
	/// <param name="e"></param>
	private void btnConfirm_Click(object sender, EventArgs e)
	{
		if (cmbDevices.SelectedItem == null)
		{
			MessageBox.Show("请选择此采集项的采集设备", "提示", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
			cmbDevices.Select();
			return;
		}
		if (string.IsNullOrEmpty(txtName.Text.Trim()))
		{
			MessageBox.Show("请输入采集项名称", "提示", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
			txtName.Select();
			return;
		}
		if (string.IsNullOrEmpty(txtIdentifier.Text.Trim()))
		{
			MessageBox.Show("请输入采集项标识，这将用于数据采集任务的参数识别中", "提示", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
			txtIdentifier.Select();
			return;
		}
		List<DAQItem> dAQItems = Common.GetDAQItems(STATION.Id);
		if ((PURPOSE == EnumFormPurpose.Add && dAQItems.Any((DAQItem t) => t.Name.ToUpper() == txtName.Text.Trim().ToUpper())) || (PURPOSE == EnumFormPurpose.Edit && dAQItems.Any((DAQItem t) => t.Name.ToUpper() == txtName.Text.Trim().ToUpper() && t.Id != DAQITEM.Id)))
		{
			MessageBox.Show("采集项名称[" + txtName.Text.Trim() + "]在当前站点中已存在，请重新输入", "提示", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
			txtName.Select();
			return;
		}
		DAQItem dAQItem = null;
		switch (PURPOSE)
		{
		case EnumFormPurpose.Add:
			dAQItem = new DAQItem
			{
				Id = Guid.NewGuid(),
				Name = txtName.Text.Trim(),
				Identifier = txtIdentifier.Text.Trim(),
				DataType = cmbDataTypes.SelectedValue.ToString(),
				DeviceId = new Guid(cmbDevices.SelectedValue.ToString()),
				StationId = STATION.Id,
				Desc = txtDesc.Text.Trim()
			};
			break;
		case EnumFormPurpose.Edit:
			dAQItem = DAQITEM;
			dAQItem.Name = txtName.Text.Trim();
			dAQItem.Identifier = txtIdentifier.Text.Trim();
			dAQItem.DataType = cmbDataTypes.SelectedValue.ToString();
			dAQItem.DeviceId = new Guid(cmbDevices.SelectedValue.ToString());
			dAQItem.StationId = STATION.Id;
			dAQItem.Desc = txtDesc.Text.Trim();
			break;
		}
		Device device = (Device)cmbDevices.SelectedItem;
		switch (device.Protocol)
		{
		case EnumProtocol.OPCUA:
		{
			UC_DAQItemParams_For_OPCUA uC_DAQItemParams_For_OPCUA = (UC_DAQItemParams_For_OPCUA)pnlContainer.Controls[0];
			if (!uC_DAQItemParams_For_OPCUA.ValidateInputs(out var msg3))
			{
				MessageBox.Show(msg3, "提示", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
				return;
			}
			dAQItem.NodeId = uC_DAQItemParams_For_OPCUA.NODEID;
			break;
		}
		case EnumProtocol.S7:
		{
			UC_DAQItemParams_For_S7 uC_DAQItemParams_For_S = (UC_DAQItemParams_For_S7)pnlContainer.Controls[0];
			if (!uC_DAQItemParams_For_S.ValidateInputs(out var msg2))
			{
				MessageBox.Show(msg2, "提示", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
				return;
			}
			dAQItem.Address = uC_DAQItemParams_For_S.ADDRESS;
			break;
		}
		case EnumProtocol.ModbusTcp:
		{
			UC_DAQItemParams_For_ModbusTcp uC_DAQItemParams_For_ModbusTcp = (UC_DAQItemParams_For_ModbusTcp)pnlContainer.Controls[0];
			if (!uC_DAQItemParams_For_ModbusTcp.ValidateInputs(out var msg4))
			{
				MessageBox.Show(msg4, "提示", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
				return;
			}
			dAQItem.Address = uC_DAQItemParams_For_ModbusTcp.ADDRESS;
			dAQItem.Length = uC_DAQItemParams_For_ModbusTcp.LENGTH;
			break;
		}
		case EnumProtocol.ModbusRtu:
		{
			UC_DAQItemParams_For_ModbusRtu uC_DAQItemParams_For_ModbusRtu = (UC_DAQItemParams_For_ModbusRtu)pnlContainer.Controls[0];
			if (!uC_DAQItemParams_For_ModbusRtu.ValidateInputs(out var msg))
			{
				MessageBox.Show(msg, "提示", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
				return;
			}
			dAQItem.Address = uC_DAQItemParams_For_ModbusRtu.ADDRESS;
			dAQItem.Length = uC_DAQItemParams_For_ModbusRtu.LENGTH;
			break;
		}
		default:
			throw new Exception($"未知的通信协议[{device.Protocol}]");
		case EnumProtocol.Socket:
			break;
		}
		this.SaveDAQItem(dAQItem);
		Close();
	}

	/// <summary>
	/// 关闭
	/// </summary>
	/// <param name="sender"></param>
	/// <param name="e"></param>
	private void btnCancel_Click(object sender, EventArgs e)
	{
		Close();
	}

	/// <summary>
	/// ESC关闭
	/// </summary>
	/// <param name="sender"></param>
	/// <param name="e"></param>
	private void DAQItemEditForm_KeyDown(object sender, KeyEventArgs e)
	{
		if (e.KeyCode == Keys.Escape)
		{
			btnCancel_Click(null, null);
		}
	}

	/// <summary>
	/// Clean up any resources being used.
	/// </summary>
	/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
	protected override void Dispose(bool disposing)
	{
		if (disposing && components != null)
		{
			components.Dispose();
		}
		base.Dispose(disposing);
	}

	/// <summary>
	/// Required method for Designer support - do not modify
	/// the contents of this method with the code editor.
	/// </summary>
	private void InitializeComponent()
	{
		this.btnCancel = new System.Windows.Forms.Button();
		this.btnConfirm = new System.Windows.Forms.Button();
		this.label1 = new System.Windows.Forms.Label();
		this.cmbDevices = new System.Windows.Forms.ComboBox();
		this.txtName = new System.Windows.Forms.TextBox();
		this.label4 = new System.Windows.Forms.Label();
		this.label5 = new System.Windows.Forms.Label();
		this.txtDesc = new System.Windows.Forms.TextBox();
		this.label6 = new System.Windows.Forms.Label();
		this.label7 = new System.Windows.Forms.Label();
		this.grpParams = new System.Windows.Forms.GroupBox();
		this.pnlContainer = new System.Windows.Forms.Panel();
		this.cmbDataTypes = new System.Windows.Forms.ComboBox();
		this.label2 = new System.Windows.Forms.Label();
		this.label3 = new System.Windows.Forms.Label();
		this.label8 = new System.Windows.Forms.Label();
		this.label9 = new System.Windows.Forms.Label();
		this.txtIdentifier = new System.Windows.Forms.TextBox();
		this.grpParams.SuspendLayout();
		base.SuspendLayout();
		this.btnCancel.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right;
		this.btnCancel.Location = new System.Drawing.Point(472, 452);
		this.btnCancel.Name = "btnCancel";
		this.btnCancel.Size = new System.Drawing.Size(75, 23);
		this.btnCancel.TabIndex = 9;
		this.btnCancel.Text = "取消(&C)";
		this.btnCancel.UseVisualStyleBackColor = true;
		this.btnCancel.Click += new System.EventHandler(btnCancel_Click);
		this.btnConfirm.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right;
		this.btnConfirm.Location = new System.Drawing.Point(391, 452);
		this.btnConfirm.Name = "btnConfirm";
		this.btnConfirm.Size = new System.Drawing.Size(75, 23);
		this.btnConfirm.TabIndex = 8;
		this.btnConfirm.Text = "确认(&S)";
		this.btnConfirm.UseVisualStyleBackColor = true;
		this.btnConfirm.Click += new System.EventHandler(btnConfirm_Click);
		this.label1.AutoSize = true;
		this.label1.Location = new System.Drawing.Point(22, 39);
		this.label1.Name = "label1";
		this.label1.Size = new System.Drawing.Size(65, 12);
		this.label1.TabIndex = 2;
		this.label1.Text = "采集设备：";
		this.cmbDevices.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
		this.cmbDevices.FormattingEnabled = true;
		this.cmbDevices.Location = new System.Drawing.Point(93, 36);
		this.cmbDevices.Name = "cmbDevices";
		this.cmbDevices.Size = new System.Drawing.Size(250, 20);
		this.cmbDevices.TabIndex = 0;
		this.cmbDevices.SelectedIndexChanged += new System.EventHandler(cmbDevices_SelectedIndexChanged);
		this.txtName.Location = new System.Drawing.Point(93, 62);
		this.txtName.MaxLength = 20;
		this.txtName.Name = "txtName";
		this.txtName.Size = new System.Drawing.Size(250, 21);
		this.txtName.TabIndex = 1;
		this.label4.AutoSize = true;
		this.label4.Location = new System.Drawing.Point(10, 65);
		this.label4.Name = "label4";
		this.label4.Size = new System.Drawing.Size(77, 12);
		this.label4.TabIndex = 2;
		this.label4.Text = "采集项名称：";
		this.label5.AutoSize = true;
		this.label5.ForeColor = System.Drawing.Color.Red;
		this.label5.Location = new System.Drawing.Point(349, 39);
		this.label5.Name = "label5";
		this.label5.Size = new System.Drawing.Size(17, 12);
		this.label5.TabIndex = 2;
		this.label5.Text = "* ";
		this.txtDesc.Location = new System.Drawing.Point(93, 142);
		this.txtDesc.Multiline = true;
		this.txtDesc.Name = "txtDesc";
		this.txtDesc.Size = new System.Drawing.Size(371, 87);
		this.txtDesc.TabIndex = 6;
		this.label6.AutoSize = true;
		this.label6.Location = new System.Drawing.Point(22, 145);
		this.label6.Name = "label6";
		this.label6.Size = new System.Drawing.Size(65, 12);
		this.label6.TabIndex = 2;
		this.label6.Text = "描    述：";
		this.label7.AutoSize = true;
		this.label7.ForeColor = System.Drawing.Color.Red;
		this.label7.Location = new System.Drawing.Point(349, 65);
		this.label7.Name = "label7";
		this.label7.Size = new System.Drawing.Size(143, 12);
		this.label7.TabIndex = 2;
		this.label7.Text = "*  在当前站点中保持唯一";
		this.grpParams.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right;
		this.grpParams.Controls.Add(this.pnlContainer);
		this.grpParams.Location = new System.Drawing.Point(12, 235);
		this.grpParams.Name = "grpParams";
		this.grpParams.Size = new System.Drawing.Size(535, 211);
		this.grpParams.TabIndex = 7;
		this.grpParams.TabStop = false;
		this.grpParams.Text = "采集项参数";
		this.pnlContainer.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right;
		this.pnlContainer.Location = new System.Drawing.Point(6, 16);
		this.pnlContainer.Name = "pnlContainer";
		this.pnlContainer.Size = new System.Drawing.Size(523, 189);
		this.pnlContainer.TabIndex = 0;
		this.cmbDataTypes.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
		this.cmbDataTypes.FormattingEnabled = true;
		this.cmbDataTypes.Location = new System.Drawing.Point(93, 116);
		this.cmbDataTypes.Name = "cmbDataTypes";
		this.cmbDataTypes.Size = new System.Drawing.Size(250, 20);
		this.cmbDataTypes.TabIndex = 3;
		this.cmbDataTypes.SelectedIndexChanged += new System.EventHandler(cmbDataTypes_SelectedIndexChanged);
		this.label2.AutoSize = true;
		this.label2.Location = new System.Drawing.Point(22, 119);
		this.label2.Name = "label2";
		this.label2.Size = new System.Drawing.Size(65, 12);
		this.label2.TabIndex = 10;
		this.label2.Text = "数据类型：";
		this.label3.AutoSize = true;
		this.label3.ForeColor = System.Drawing.Color.Red;
		this.label3.Location = new System.Drawing.Point(349, 119);
		this.label3.Name = "label3";
		this.label3.Size = new System.Drawing.Size(11, 12);
		this.label3.TabIndex = 11;
		this.label3.Text = "*";
		this.label8.AutoSize = true;
		this.label8.Location = new System.Drawing.Point(10, 92);
		this.label8.Name = "label8";
		this.label8.Size = new System.Drawing.Size(77, 12);
		this.label8.TabIndex = 2;
		this.label8.Text = "采集项标识：";
		this.label9.AutoSize = true;
		this.label9.ForeColor = System.Drawing.Color.Red;
		this.label9.Location = new System.Drawing.Point(349, 92);
		this.label9.Name = "label9";
		this.label9.Size = new System.Drawing.Size(17, 12);
		this.label9.TabIndex = 2;
		this.label9.Text = "* ";
		this.txtIdentifier.Location = new System.Drawing.Point(93, 89);
		this.txtIdentifier.MaxLength = 30;
		this.txtIdentifier.Name = "txtIdentifier";
		this.txtIdentifier.Size = new System.Drawing.Size(250, 21);
		this.txtIdentifier.TabIndex = 2;
		base.AutoScaleDimensions = new System.Drawing.SizeF(6f, 12f);
		base.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
		base.ClientSize = new System.Drawing.Size(559, 487);
		base.Controls.Add(this.label3);
		base.Controls.Add(this.cmbDataTypes);
		base.Controls.Add(this.label2);
		base.Controls.Add(this.grpParams);
		base.Controls.Add(this.txtDesc);
		base.Controls.Add(this.txtIdentifier);
		base.Controls.Add(this.txtName);
		base.Controls.Add(this.label6);
		base.Controls.Add(this.label9);
		base.Controls.Add(this.cmbDevices);
		base.Controls.Add(this.label7);
		base.Controls.Add(this.label8);
		base.Controls.Add(this.label5);
		base.Controls.Add(this.label4);
		base.Controls.Add(this.label1);
		base.Controls.Add(this.btnConfirm);
		base.Controls.Add(this.btnCancel);
		base.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
		base.MaximizeBox = false;
		base.Name = "DAQItemEditForm";
		base.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
		this.Text = "DAQItemEditForm";
		base.Load += new System.EventHandler(DAQItemEditForm_Load);
		base.KeyDown += new System.Windows.Forms.KeyEventHandler(DAQItemEditForm_KeyDown);
		this.grpParams.ResumeLayout(false);
		base.ResumeLayout(false);
		base.PerformLayout();
	}
}
